package com.lm.selenium.controller;

import com.lm.selenium.ele.BatchResult;
import com.lm.selenium.ele.PageResult;
import com.lm.selenium.service.CrawlerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/crawl")
public class CrawlerController {

    @Autowired
    private CrawlerService crawlerService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @PostMapping("/batch")
    public ResponseEntity<BatchResult> batchCrawl(@RequestBody List<String> urls) {
        List<Future<PageResult>> futures = urls.stream()
                .map(url -> taskExecutor.submit(() -> crawlSinglePage(url)))
                .collect(Collectors.toList());

        List<PageResult> results = new ArrayList<>();

        for (int i = 0; i < urls.size(); i++) {
            try {
                PageResult result = futures.get(i).get(30, TimeUnit.SECONDS);
                results.add(result);
            } catch (TimeoutException e) {
                results.add(new PageResult(urls.get(i), null, 30_000L, "Timeout"));
            } catch (Exception e) {
                results.add(new PageResult(urls.get(i), null, 0L, "Failed: " + e.getMessage()));
            }
        }

        return ResponseEntity.ok(new BatchResult(results));
    }

    private PageResult crawlSinglePage(String url) {
        long start = System.currentTimeMillis();
        try {
            String content = crawlerService.fetchPage(url);
            return new PageResult(url, content, System.currentTimeMillis() - start, null);
        } catch (Exception e) {
            return new PageResult(url, null, System.currentTimeMillis() - start, e.getMessage());
        }
    }
}
